from random import randint

import pygame
from pygame.locals import *
from sys import exit
import  math

pygame.init()
screen = pygame.display.set_mode((640, 640), 0, 32)

clock = pygame.time.Clock()

class ArrayLine():

    def __init__(self, startP, endP,color, sc, isdash=False):

        self.StartPoint=startP
        self.EndPoint=endP
        self.Color=color
        self.IsDashLine=isdash
        self.Scree=sc



    def DrawLine(self):
        if not self.IsDashLine:

           pygame.draw.line(self.Screen,self.Color,self.StartPoint,self.EndPoint,width=1)

    def Distance(self):
        return math.sqrt((self.StartPoint[0]-self.EndPoint[0])**2+(self.StartPoint[1]-self.EndPoint[1])**2)




    def DrawArray(self):
          Length=self.Distance()/10

          if (self.StartPoint[0]-self.EndPoint[0])==0 & self.EndPoint[1]>self.StartPoint[1] :
              Angle=math.pi
          elif (self.StartPoint[0]-self.EndPoint[0])==0 & self.EndPoint[1]<self.StartPoint[1]:
              Angle=-math.pi
          else:
              Angle=math.atan((self.StartPoint[1]-self.EndPoint[1])/(self.StartPoint[0]-self.EndPoint[0]))

          Point1=(self.EndPoint[0]+Length*math.cos(Angle), self.EndPoint[1]+Length*math.sin(Angle))

          Edge=Length/math.cos(math.pi/3)





class MoveCylcle():

    def __init__(self, x, y,sr,isConta=0):
        self.x = x
        self.y=y
        self.Cycle=(x,y)
        if isConta==0:
            self.Color = (255,0,0)
        elif isConta==1: self.Color=(255,255,0)
        else: self.Color=(0,255,0)
        self.ContaStatus=isConta

        self.screen=sr
        self.willTOMove=5
        self.Radis=10
        self.Ration2Conta=0.2
        self.Ration2Recovery=0.005

    def move(self):
        self.x += randint(-self.willTOMove, self.willTOMove)
        self.y += randint(-self.willTOMove, self.willTOMove)
        if self.x > 640 - 10:

            self.x = 640 - 10
        elif self.x < 0:

            self.x = 0.

        if self.y > 640 - 10:

            self.y = 640 - 10
        elif self.y < 0:

            self.y = 0

        self.Draw()

    def FindNearestCyc(self,Cycs=[]):
        try:
            Dis=1000000
            CycMin=Cycs[0]
            for cyc in Cycs:
                d=self.Distance(cyc)
                if d<=Dis:
                    Dis=d
                    CycMin=cyc

            pygame.draw.line(self.screen,(123,110,255),(self.x,self.y),(CycMin.x,CycMin.y))
        except IndexError:
            return


    def Draw(self):
        pygame.draw.circle(self.screen, self.Color, (self.x, self.y), self.Radis)

    def Distance(self,Cyc):
        return math.sqrt((self.x-Cyc.x)**2+(self.y-Cyc.y)**2)

    def IsCollision(self,Cyc):
        if self.Distance(Cyc)<=self.Radis+Cyc.Radis:
            return True
        else: return False

    def Contaminate(self, Cyclist=[],BadList=[]):
        DisList=[]
        for ss in Cyclist:
            dis=self.Distance(ss)
            DisList.append(dis)
            if self.IsCollision(ss):
               if randint(0,100)<=math.floor( self.Ration2Conta*100 ):

                   ss.Color=self.Color
                   ss.ContaStatus=self.ContaStatus
                   BadList.append(ss)
                   Cyclist.remove(ss)

                   return (ss,self)
        return None

    def Recovery(self, BadList=[],GoodList=[]):

        if self.ContaStatus==0:

            if randint(0, 100) <= math.floor(self.Ration2Recovery * 100):
                self.Color=(0,255,255)
                self.ContaStatus=1
                BadList.remove(self)
                GoodList.append(self)







BadList=[]
GoodList=[]
VaccineList=[]

MasterList=[]
SalveList=[]

for i in range(150):

    GoodList.append(MoveCylcle(randint(0,640), randint(0,640), screen, 1))

for i in range(50):

    VaccineList.append(MoveCylcle(randint(0,640), randint(0,640), screen, 2))

for i in range(10):
    BadList.append(MoveCylcle(randint(0,640), randint(0,640), screen, 0))


TimeTotal=0.0

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.fill((255,255,255))

    for ii in GoodList:
        ii.move()
    for jj in BadList:
        jj.move()
        jj.Recovery(BadList,GoodList)

    for KK in VaccineList:
        KK.move()

    time_passed = clock.tick(30)
    TimeTotal+=time_passed / 1000.0

    if TimeTotal>0:

        for mov in BadList:

            a=mov.Contaminate(GoodList,BadList)

            if a != None:
                SalveList.append(a[0])
                MasterList.append(a[1])
            mov.FindNearestCyc(GoodList)

        # index=0
        # for M in MasterList:
        #     pygame.draw.line(screen,(255,0,0),(M.x,M.y),(SalveList[index].x,SalveList[index].y),2)
        #     index+=1
        #



    pygame.display.set_caption("Time passed - %.3f" % TimeTotal)












    pygame.display.update()



